package com.itfreer.data.metadata;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import com.itfreer.data.config.ConfigVersionService;
import com.itfreer.data.metadata.dao.DefaultDictionaryDao;
import com.itfreer.data.metadata.entity.DataDictionaryEntity;
import com.itfreer.form.api.BaseDao;
import com.itfreer.form.api.BaseServiceImp;
import com.itfreer.form.api.DataInputResult;
import com.itfreer.form.api.dictionary.DictionaryEntity;
import com.itfreer.form.api.dictionary.DictionaryLocalService;

/**
 * 定义字典服务
 */
@Component("DefaultDictionaryServiceImp")
public class DefaultDictionaryServiceImp extends BaseServiceImp<DataDictionaryEntity>
		implements DefaultDictionaryService, ApplicationListener<ContextRefreshedEvent> {

	@Autowired(required = false)
	private DefaultDictionaryDao dictionaryDao;
	@Autowired(required = false)
	private ConfigVersionService configVersionService;

	/**
	 * 字典缓存服务
	 */
	@Autowired(required = false)
	private DictionaryLocalService dictionaryCache;

	@Override
	protected BaseDao<DataDictionaryEntity> getDao() {
		return dictionaryDao;
	}

	/**
	 * 是否是树表
	 */
	protected boolean isTree() {
		return true;
	}

	/**
	 * 树的PID字段名
	 */
	protected String getTreePIDFieldName() {
		return "pid";
	}

	/**
	 * 系统启动后加载该方法
	 * 让配置字典数据来替换系统字典
	 */
	@Override
	public void onApplicationEvent(ContextRefreshedEvent event) {
		if (event.getApplicationContext().getParent() == null) {
			initDictionary();
		}
	}
	
	/**
	 * 是否为租户间共享实体对象
	 */
	protected boolean isShareTenant() {
		return true;
	}

	/**
	 * 获取租户间共享字段名称 用于SAAS下数据管理
	 */
	protected String getShareTenantFieldName() {
		return "shareTenantID";
	}

	private void initDictionary() {
		if (dictionaryCache == null) {
			return;
		}
		if (getDao() == null) {
			return;
		}

		List<DataDictionaryEntity> list = getDao().getEntitys(null, null);
		if (list != null && list.size() > 0) {
			HashMap<String, List<DictionaryEntity>> cacheList = new HashMap<String, List<DictionaryEntity>>();

			for (DataDictionaryEntity entity : list) {
				String dicName = entity.getDicName().toLowerCase();
				DictionaryEntity item = convert(entity);

				if (cacheList.containsKey(dicName)) {
					cacheList.get(dicName).add(item);
				} else {
					List<DictionaryEntity> clist = new ArrayList<DictionaryEntity>();
					clist.add(item);
					cacheList.put(dicName, clist);
				}
			}

			for (String dic : cacheList.keySet()) {
				dictionaryCache.init(dic, cacheList.get(dic));
			}
		}
	}

	public void addDictionary(String dicName, DictionaryEntity dictionary) {
		if (dictionaryCache == null) {
			return;
		}

		dictionaryCache.add(dicName.toLowerCase(), dictionary);
	}

	public void updateDictionary(String dicName, DictionaryEntity dictionary) {
		if (dictionaryCache == null) {
			return;
		}

		dictionaryCache.update(dicName.toLowerCase(), dictionary);
	}

	public void deleteDictionary(String dicName, String guid) {
		if (dictionaryCache == null) {
			return;
		}

		dictionaryCache.delete(dicName.toLowerCase(), guid);
	}

	private DictionaryEntity convert(DataDictionaryEntity entity) {
		DictionaryEntity toEntity = new DictionaryEntity();
		BeanUtils.copyProperties(entity, toEntity);
		return toEntity;
	}

	/**
	 * 添加实体
	 * 
	 * @param entity
	 *            添加实体
	 * @return
	 */
	@Override
	public DataDictionaryEntity add(DataDictionaryEntity entity) {
		entity = super.add(entity);
		addDictionary(entity.getDicName(), convert(entity));
		configVersionService.addVersion();
		return entity;
	}

	/**
	 * 更新实体
	 * 
	 * @param guid
	 *            唯一值
	 * @param entity
	 *            实体
	 * @return
	 */
	@Override
	public DataDictionaryEntity update(DataDictionaryEntity entity) {
		entity = super.update(entity);
		updateDictionary(entity.getDicName(), convert(entity));
		configVersionService.addVersion();
		return entity;
	}

	/**
	 * 删除实体
	 * 
	 * @param guid
	 *            唯一值
	 */
	@Override
	public Boolean delete(String guid) {
		// 配置事务策略
		DefaultTransactionDefinition def = new DefaultTransactionDefinition();
		def.setName("planOne-transaction");
		def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
		// 设置状态点
		TransactionStatus status = transactionManager.getTransaction(def);
		Boolean result = false;
		try {
			DataDictionaryEntity entity = super.getEntity(guid);
			result = super.delete(guid);
			deleteDictionary(entity.getDicName(), guid);
			configVersionService.addVersion();
		} catch (Exception e) {
			transactionManager.rollback(status);
			throw e;
		}
		transactionManager.commit(status);
		return result;
	}

	/**
	 * 删除实体
	 * 
	 * @param guid
	 *            唯一值
	 */
	@Override
	public void delete(String dn, String guid) {
		DataDictionaryEntity entity = super.getEntity(guid);
		dictionaryDao.deleteEx(dn, guid);
		deleteDictionary(entity.getDicName(), guid);
		configVersionService.addVersion();
	}

	/**
	 * 指量删除实体
	 * 
	 * @param guid
	 *            唯一值集
	 */
	@Override
	public void deletes(String dn, String guids) {
		String[] ids = guids.split(",");
		for (String id : ids) {
			this.delete(dn, id);
		}
	}

	/**
	 * 根据字典名称，获取所有字典数据
	 * 
	 * @param dicName
	 * @return
	 */
	@Override
	public List<DictionaryEntity> getEntitys(String dicName) {
		Map<String, Object> where = new HashMap<String, Object>();
		where.put("dicName", dicName);
		Map<String, Integer> order = new HashMap<String, Integer>();
		order.put("code", 0);

		List<DataDictionaryEntity> list = super.getEntitys(where, order);

		List<DictionaryEntity> dictionaryEntitys = new ArrayList<>();
		for (DataDictionaryEntity entity : list) {
			DictionaryEntity item = convert(entity);
			dictionaryEntitys.add(item);
		}

		return dictionaryEntitys;
	}

	/**
	 * 导入Excel数据
	 * 
	 * @param fileNmae
	 *            文件名
	 * @param fileStream
	 *            数据文件
	 * @param inputID
	 *            导入配置
	 * @param startrow
	 *            开始导入行
	 * @return
	 */
	@Override
	public DataInputResult input(String fileName, InputStream fileStream, String inputID, Integer startrow) {
		configVersionService.addVersion();
		return super.input(fileName, fileStream, inputID, startrow);
	}

	/**
	 * 导入Shape数据
	 * 
	 * @param fileNmae
	 *            文件名
	 * @return
	 */
	@Override
	public DataInputResult importShape(String fileName, String inputID) {
		configVersionService.addVersion();
		return super.importShape(fileName, inputID);
	}
}